package valuecomusa.fijibus.eticket.shorthaul;


import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.MediaPlayer;
//import android.nfc.NfcAdapter;
import android.os.*;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
import com.valuecomusa.Enums;
import com.valuecomusa.bmf.NfcCardInfo;
import org.kobjects.base64.Base64;
import valuecomusa.fijibus.eticket.*;
import valuecomusa.fijibus.eticket.db.shorthaul.BusinessDBHandler;
import valuecomusa.fijibus.eticket.db.shorthaul.GpsDBHandler;
import valuecomusa.fijibus.eticket.dialog.checkin_topup;
import valuecomusa.fijibus.eticket.dto.GpsCurrentLocationValue;
import valuecomusa.fijibus.eticket.dto.StagesOfRouteValue;
import valuecomusa.fijibus.eticket.ws.MemberValue;
import valuecomusa.fijibus.eticket.ws.PassengerTypeValue;
import valuecomusa.fijibus.eticket.ws.TransactionValue;
import valuecomusa.fijibus.eticket.ws.VoucherValue;

import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

public class CheckInV2TapIn extends SunbeamActivity
{
    private static int counter = 1;
    private String TAG = "CheckInV2TapIn";
    //--
    private StagesOfRouteValue currentLocation;
    private RadioGroup adult;
    private RadioGroup senior;
    private RadioGroup child;
    private RadioGroup disabled;
    //private RadioGroup exempt;
    private RadioGroup student;

    private int passengerCount = 0;
    private double totalAmount;
    private double xStageFare;
    private int stageCount;
    //--
    private double minFare;

    private TextView totalAmountTextView;
    //private CheckBox printReceipt;

    private BusinessDBHandler db;
    private GpsDBHandler gpsDb;

//	private NfcAdapter nfcAdapter;
//	private PendingIntent mPendingIntent;

    private List<PassengerTypeValue> passengerTypeList;

    //private int checkinType = 0;
    private Timer autoSubmit;
    private boolean isAutoSubmit = false;
    //--
    private ProgressDialog progress;

    public CheckInV2TapIn()
    {
        TAG = TAG + "." + counter++;
        if (counter > 1000000)
            counter = 1;
    }

    public int getSelectedPassengers(RadioGroup g)
    {
        if (g == null)
            return 0;

        int selected = g.getCheckedRadioButtonId();
        if (selected < 0)
            return 0;

        RadioButton b = (RadioButton) findViewById(selected);

        return Integer.parseInt(b.getText().toString());
    }

    private double GetPassengerTypeDiscount(String type)
    {
        for (PassengerTypeValue xx : this.passengerTypeList)
        {
            if (xx.Type.toLowerCase().equals(type.toLowerCase()))
                return xx.Discount / 100;
        }
        return 0;
    }

    public void CalcTotalAmount()
    {
        int tmpNoOf = 0;
        try
        {
            totalAmount = 0;
            passengerCount = 0;
            double discount = 0;
            //--
            tmpNoOf = getSelectedPassengers(adult);
            totalAmount = tmpNoOf * xStageFare * (1 - GetPassengerTypeDiscount("adult"));
            passengerCount = tmpNoOf;
            //--
            tmpNoOf = getSelectedPassengers(senior);
            totalAmount += tmpNoOf * xStageFare * (1 - GetPassengerTypeDiscount("senior"));
            passengerCount += tmpNoOf;
            //--
            tmpNoOf = getSelectedPassengers(child);
            totalAmount += tmpNoOf * xStageFare * (1 - GetPassengerTypeDiscount("child"));
            passengerCount += tmpNoOf;
            //--
            tmpNoOf = getSelectedPassengers(disabled);
            totalAmount += tmpNoOf * xStageFare * (1 - GetPassengerTypeDiscount("disabled"));
            passengerCount += tmpNoOf;
            //--
            /*tmpNoOf = getSelectedPassengers(exempt);
			totalAmount += tmpNoOf * xStageFare * (1 - GetPassengerTypeDiscount("exempt"));
            passengerCount += tmpNoOf;*/
            //--
            tmpNoOf = getSelectedPassengers(student);
            totalAmount += tmpNoOf * xStageFare * (1 - GetPassengerTypeDiscount("student"));
            passengerCount += tmpNoOf;
            //--
            totalAmountTextView.setText(String.valueOf(WorkingSession.getInstance().RoundMoney(totalAmount)));
        }
        catch (Exception ex)
        {
            Log.e(TAG, ex.getMessage());
        }
    }

    private void Initialize()
    {
        try
        {
            currentLocation = null;
            passengerCount = 0;
            totalAmount = 0;
            xStageFare = 0;
            stageCount = 1;
            passengerTypeList = null;

            //--
            HandlerThread uiThread = new HandlerThread("UIThreadHandler");//to prepare a looper
            uiThread.start();
            uiThreadHandler = new UIThreadHandler(uiThread.getLooper()); //to process UI such as AlertDialog,...
            //--
            progress = new ProgressDialog(this);
            progress.setMessage("Waiting...");
            progress.setCancelable(false);

            //--
//			nfcAdapter = NfcAdapter.getDefaultAdapter(this);
//			mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
//					getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
            //--
            db = new BusinessDBHandler(CheckInV2TapIn.this);
            gpsDb = new GpsDBHandler(CheckInV2TapIn.this);
            //--
            minFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, 1);
            //--
            passengerTypeList = db.getPassengerType();
            if (passengerTypeList == null || passengerTypeList.size() == 0)
            {
                Log.d(TAG, "Could not get Passenger Type discount");
                WorkingSession.getInstance().ShowToast(this,
                                                       "Could not get Passenger Type's discount",
                                                       Toast.LENGTH_LONG);
                finish();
                return;
            }//--

            totalAmountTextView = (TextView) findViewById(R.id.tvFare);
            //printReceipt = (CheckBox) findViewById(R.id.chkPrintReceipt);
            //---
            adult = (RadioGroup) findViewById(R.id.Adult);
            senior = (RadioGroup) findViewById(R.id.Senior);
            child = (RadioGroup) findViewById(R.id.Child);
            disabled = (RadioGroup) findViewById(R.id.Disabled);
            //exempt = (RadioGroup) findViewById(R.id.Exempt);
            student = (RadioGroup) findViewById(R.id.Student);
        }
        catch (Exception ex)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2TapIn.this,
                    "[TapIn] Initialize Error",
                    "System error, please contact your administrator.\n" + ex.getMessage());
            finish();
        }
    }

    private void fillMemberInfo()
    {
        TextView tvtmp = (TextView) findViewById(R.id.tvCustID);
        tvtmp.setText(WorkingSession.getInstance().currentPassenger.UserName + " ("
                              + WorkingSession.getInstance().currentPassenger.getFullName() + ")");

        totalAmountTextView.setText(WorkingSession.getInstance().decimalFormat.format(totalAmount));
        //--
        tvtmp = (TextView) findViewById(R.id.checkin_text_current_balance);
        tvtmp.setText(WorkingSession.getInstance().decimalFormat.format(
                WorkingSession.getInstance().currentPassenger.CurrentBalance));
        if (WorkingSession.getInstance().currentPassenger.CurrentBalance < 0)
            tvtmp.setTextColor(Color.RED);
        else
            tvtmp.setTextColor(Color.parseColor("#005569"));
        //--
        if (WorkingSession.getInstance().currentPassenger.Picture != null &&
                WorkingSession.getInstance().currentPassenger.Picture.length() > 0)
        {
            try
            {
                byte[] imageData = Base64.decode(WorkingSession.getInstance().currentPassenger.Picture);
                Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
                String filePath = Utilities.SaveBitmapToSdCard(
                        CheckInV2TapIn.this,
                        bitmap,
                        WorkingSession.getInstance().currentPassenger.ISN + ".jpg");

                ImageView memberImage = (ImageView) findViewById(R.id.checkin_member_image);
                memberImage.setImageBitmap(BitmapFactory.decodeFile(filePath));
            }
            catch (Exception ex)
            {
                Log.e(TAG, "[MemberImage] " + ex.getMessage());
            }
        }

        if (WorkingSession.getInstance().currentPassenger.PassengerType.toLowerCase().equals("adult"))
            adult.check(R.id.Adult1);
        else if (WorkingSession.getInstance().currentPassenger.PassengerType.toLowerCase().equals("senior"))
            senior.check(R.id.Senior1);
        else if (WorkingSession.getInstance().currentPassenger.PassengerType.toLowerCase().equals("child"))
            child.check(R.id.Child1);
        else if (WorkingSession.getInstance().currentPassenger.PassengerType.toLowerCase().equals("disabled"))
            disabled.check(R.id.Disabled1);
        /*else if (WorkingSession.getInstance().currentPassenger.PassengerType.toLowerCase().equals("exempt"))
            exempt.check(R.id.Exempt1);*/
        else if (WorkingSession.getInstance().currentPassenger.PassengerType.toLowerCase().equals("student"))
            student.check(R.id.Student1);
    }

    private void showStageButton()
    {
        RadioGroup stageGroup1 = (RadioGroup) findViewById(R.id.stageGroup1);
        RadioGroup stageGroup2 = (RadioGroup) findViewById(R.id.stageGroup2);

        int xCount = db.getStageCountOfRoute(WorkingSession.getInstance().journalRoute.ISN);
        if (xCount <= 0)
        {
            stageGroup1.setVisibility(View.GONE);
            stageGroup2.setVisibility(View.GONE);
            return;
        }
        if (xCount < 4)
        {
            stageGroup2.setVisibility(View.GONE);
            if (xCount < 3)
                findViewById(R.id.checkin_btStage3).setVisibility(View.GONE);
            if (xCount < 2)
                findViewById(R.id.checkin_btStage2).setVisibility(View.GONE);
        }
        else
        {
            if (xCount < 7)
                findViewById(R.id.checkin_btStage7).setVisibility(View.GONE);
            if (xCount < 6)
                findViewById(R.id.checkin_btStage6).setVisibility(View.GONE);
            if (xCount < 5)
                findViewById(R.id.checkin_btStage5).setVisibility(View.GONE);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate...");
        // --
        setContentView(R.layout.check_in_v2_tap_in);
        // --
        doCommon();
        Initialize();
        WorkingSession.getInstance().currentActivity = CheckInV2TapIn.this;
        //--
        Log.d(TAG, "[onCreate] WorkingSession.getInstance().setSAMReaderEventListener(samReaderEvent, true);");
        WorkingSession.getInstance().setSAMReaderEventListener(samReaderEvent, true);
        //--
        List<StagesOfRouteValue> stageList = db.getStagesOfRoute(WorkingSession.getInstance().journalRoute.ISN);
        ArrayAdapter<StagesOfRouteValue> stages = new ArrayAdapter<StagesOfRouteValue>(this,
                                                                                       android.R.layout.simple_dropdown_item_1line, stageList);
        //---
        Spinner xx = (Spinner) findViewById(R.id.checkin_current_location);
        xx.setAdapter(stages);
        xx.setOnItemSelectedListener(currentLocationItemClick);
        //---
        Button xxClick = (Button) findViewById(R.id.checkin_current_location_click);
        xxClick.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Spinner xx = (Spinner) findViewById(R.id.checkin_current_location);
                xx.performClick();
            }
        });
        //--
        RegisterEvent();
        //--
        RegisterPassengerTypeTouchEvent();
        RegisterStageTouchEvent();
        //--
        showStageButton();
        //--
        findViewById(R.id.checkin_btn_tap_out).setEnabled(true);
        RadioGroup stageGroup1 = (RadioGroup) findViewById(R.id.stageGroup1);
        stageGroup1.check(R.id.checkin_btn_tap_out);
        //--
        CalcTotalAmount();
        //---
        fillMemberInfo();

        //---
        if (xStageFare < 0)
        {
            WorkingSession.getInstance().ShowToast(this, "Could not get Fare", Toast.LENGTH_LONG);
        }
        //--
        GpsCurrentLocationValue currentGpsLocation = gpsDb.getCurrentLocation(
                WorkingSession.getInstance().setupJournal.ISN);
        if (currentGpsLocation != null)
        {
            Log.d(TAG, String.format("Current location: %d", currentGpsLocation.ClosestStage));
            int idx = -1;
            for (int i = 0; i < stageList.size(); i++)
            {
                Log.d(TAG, String.format("Stage: %d", stageList.get(i).StageISN));
                if (stageList.get(i).StageISN == currentGpsLocation.ClosestStage &&
                        stageList.get(i).BusStationISN == currentGpsLocation.ClosestBusStation)
                {
                    idx = i;
                    break;
                }
            }
            if (idx != -1)
                xx.setSelection(idx);
        }
        //-- play bula voice
        //Utilities.PlayMedia(CheckIn.this, "bula.mp3");
        //---
        CheckBalanceAndAutoSubmit();
    }

    private AdapterView.OnItemSelectedListener currentLocationItemClick = new AdapterView.OnItemSelectedListener()
    {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long rowId)
        {
            StagesOfRouteValue sel = (StagesOfRouteValue) parent.getItemAtPosition(position);

            Log.d(TAG, String.format("Select location: %d - %s", sel.StageISN, sel.StationName));
            currentLocation = sel;
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView)
        {
            currentLocation = null;
        }
    };

    private void RegisterEvent()
    {
        //--
        adult.setOnCheckedChangeListener(onPassengerCheckedChange);
        senior.setOnCheckedChangeListener(onPassengerCheckedChange);
        child.setOnCheckedChangeListener(onPassengerCheckedChange);
        disabled.setOnCheckedChangeListener(onPassengerCheckedChange);
        //exempt.setOnCheckedChangeListener(onPassengerCheckedChange);
        student.setOnCheckedChangeListener(onPassengerCheckedChange);
        //---
        RadioGroup stageSelect;
        //---stage group 1
        stageSelect = (RadioGroup) findViewById(R.id.stageGroup1);
        stageSelect.setOnCheckedChangeListener(OnStageCheckedChange);
        //---stage group 2
        stageSelect = (RadioGroup) findViewById(R.id.stageGroup2);
        stageSelect.setOnCheckedChangeListener(OnStageCheckedChange);
        //--
        Button cancel = (Button) findViewById(R.id.check_in_tap_cancel);
        cancel.setOnClickListener(onCancelClick);
        cancel.setOnTouchListener(onTouch);
        //--
        Button submit = (Button) findViewById(R.id.check_in_tap_submit);
        submit.setOnClickListener(onSubmitClick);
        submit.setOnTouchListener(onTouch);
        //--
        Button tap_cash_topup = (Button) findViewById(R.id.checkin_tap_cash_topup);
        tap_cash_topup.setOnClickListener(onCashAndTopUpClick);
        tap_cash_topup.setOnTouchListener(onTouch);
    }

    private MediaPlayer errorVoice;

    private void CheckBalanceAndAutoSubmit()
    {
        if (WorkingSession.getInstance().currentPassenger.CurrentBalance < minFare)
        {
            Intent runActivity = new Intent(CheckInV2TapIn.this, checkin_topup.class);
            runActivity.putExtra("REQUIRED_FARE_AMOUNT", minFare);
            startActivityForResult(runActivity, Declarations.REQUEST_REQUIRED_TOP_UP);
            return;
        }
        autoSubmit = new Timer();
        isAutoSubmit = true;
        autoSubmit.scheduleAtFixedRate(
                autoSubmitTask,
                0,
                1000);
    }

    private UIThreadHandler uiThreadHandler;

    @Override
    protected void onStart()
    {
        super.onStart();
        Log.d(TAG, "onStart...");

    }

    private TimerTask autoSubmitTask = new TimerTask()
    {
        @Override
        public void run()
        {
            uiThreadHandler.sendEmptyMessage(UIThreadHandler.MSG_COUNT_DOWN);
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK)
        {
            if (requestCode == Declarations.REQUEST_CASH_TOP_UP)
            {
                double cashTopUpAmount = data.getDoubleExtra("CASH_TOPUP_AMOUNT", 0);
                if (cashTopUpAmount > 0)
                {
                    //doPayCashAndTopUp(cashTopUpAmount);
                    DoCheckInAsync xTask = new DoCheckInAsync(
                            CheckInV2TapIn.this,
                            progress,
                            DoCheckInAsync.CHECK_IN_BY_CASH_TOP_UP
                    );
                    xTask.execute(cashTopUpAmount);
                }
            }
            /*else if (requestCode == Declarations.REQUEST_STUDENT_VOUCHER)
            {
                double discountAmount = data.getDoubleExtra("VOUCHER_DISCOUNT_AMOUNT", 0);
                String voucherType = data.getStringExtra("VOUCHER_TYPE");
                int collectBalanceType = data.getIntExtra("VOUCHER_COLLECT_BALANCE_TYPE",
                        StudentVoucher.COMPLETE_PAYMENT_BY_VOUCHER);
                double collectAmount = data.getDoubleExtra("VOUCHER_COLLECT_CASH", 0);
                //--
                *//*doPayByStudentVoucher(
                        voucherType,
                        discountAmount,
                        collectBalanceType,
                        collectAmount);*//*
                DoCheckInAsync xTask = new DoCheckInAsync(
                        CheckInV2TapIn.this,
                        progress,
                        DoCheckInAsync.CHECK_IN_BY_STUDENT_VOUCHER
                );
                xTask.execute(
                        voucherType,
                        discountAmount,
                        collectBalanceType,
                        collectAmount
                );
            }*/
            else if (requestCode == Declarations.REQUEST_REQUIRED_TOP_UP)
            {
                double topUpAmount = data.getDoubleExtra("TOP_UP_AMOUNT_RESULT", 0);
                if (topUpAmount > 0)
                {
                    if (AddTopUpTransaction(topUpAmount))
                    {
                        WorkingSession.getInstance().ShowToast(
                                CheckInV2TapIn.this,
                                "Add Top Up transaction successful",
                                Toast.LENGTH_SHORT
                                                              );

                        //doTapIn();
                        DoCheckInAsync xTask = new DoCheckInAsync(
                                CheckInV2TapIn.this,
                                progress,
                                DoCheckInAsync.CHECK_IN_BY_TAP_IN
                        );
                        xTask.execute();
                    }
                }
            }
        }
    }

    private boolean AddTopUpTransaction(double amount)
    {
        //--create top up transaction
        TransactionValue trans = WorkingSession.getInstance().CreateTransaction(
                CheckInV2TapIn.this,
                "TOP-UP",
                "Cash",
                0,
                0, 0,
                amount,
                null, //voucher
                null, null,
                0,
                0, 0, 0, 0, 0, 0,
                null,
                ";;;;;");
        if (trans == null)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2TapIn.this,
                    "Create Transaction Error",
                    "System Error.\nCould not create transaction, please contact your administrator."
                                                        );

            return false;
        }
        try
        {
            long rx = db.addTransaction(trans);
            trans.ISN = (int) rx;
        }
        catch (Exception ex)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2TapIn.this,
                    "Create Transaction Error",
                    "System Error.\nCould not create transaction, please contact your administrator."
                                                        );

            return false;
        }
        //--update passenger balance
        WorkingSession.getInstance().currentPassenger.CurrentBalance += trans.TopUpAmount;
        int x = db.updateMemberBalance(
                WorkingSession.getInstance().currentPassenger.ISN,
                WorkingSession.getInstance().currentPassenger.CurrentBalance);

        return true;
    }

    private int InputValidate(int paymentType)
    {
        int inputValidateResult = 1;

        if (currentLocation == null)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2TapIn.this,
                    "Error",
                    "Please select current location");

            inputValidateResult = 0;
        }
        else if (passengerCount <= 0)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2TapIn.this,
                    "Error",
                    "Please choose passenger type \n(Adult, Senior, Child, Disabled or Student)"
                                                        );

            inputValidateResult = 0;
        }
        else if (WorkingSession.getInstance().currentPassenger.CurrentBalance < minFare)
        {
            WorkingSession.getInstance().ShowToast(
                    CheckInV2TapIn.this,
                    "Customer is not enough balance for check-in",
                    Toast.LENGTH_SHORT
                                                  );

            inputValidateResult = 2;
        }

        return inputValidateResult;
    }

    OnClickListener onCashAndTopUpClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            if (autoSubmit != null)
                autoSubmit.cancel();
            isAutoSubmit = false;
            //--

            if (InputValidate(2) < 0) //not validate or waiting for confirm
                return;

            Intent input = new Intent(CheckInV2TapIn.this, Cash_TopUp.class);
            input.putExtra("FARE_AMOUNT", totalAmount);
            startActivityForResult(input, Declarations.REQUEST_CASH_TOP_UP); //will be continued at onActivityResult
        }


    };

    private int stageClearGroup;

    private RadioGroup.OnCheckedChangeListener OnStageCheckedChange = new RadioGroup.OnCheckedChangeListener()
    {
        @Override
        public void onCheckedChanged(RadioGroup radioGroup, int i)
        {
            Log.d(TAG, "[OnStageCheckedChange] id: " + i);

            if (radioGroup.getId() == stageClearGroup)
            {
                stageClearGroup = 0;
                return;
            }

            if (i == -1)
                return;

            GetFare(radioGroup.getCheckedRadioButtonId());
            CalcTotalAmount();
        }
    };

    private void GetFare(int stageButtonId)
    {
        if (stageButtonId == R.id.checkin_btn_tap_out)
        {
            int xCount = db.getStageCountOfRoute(WorkingSession.getInstance().journalRoute.ISN);
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, xCount);
            stageCount = xCount;
        }
        else if (stageButtonId == R.id.checkin_btStage1)
        {
            xStageFare = minFare;
            stageCount = 1;
        }
        else if (stageButtonId == R.id.checkin_btStage2)
        {
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, 2);
            stageCount = 2;
        }
        else if (stageButtonId == R.id.checkin_btStage3)
        {
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, 3);
            stageCount = 3;
        }
        else if (stageButtonId == R.id.checkin_btStage4)
        {
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, 4);
            stageCount = 4;
        }
        else if (stageButtonId == R.id.checkin_btStage5)
        {
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, 5);
            stageCount = 5;
        }
        else if (stageButtonId == R.id.checkin_btStage6)
        {
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, 6);
            stageCount = 6;
        }
        else if (stageButtonId == R.id.checkin_btStage7)
        {
            xStageFare = db.getStageFare(WorkingSession.getInstance().journalRoute.ISN, 7);
            stageCount = 7;
        }

        if (xStageFare < 0)
        {
            WorkingSession.getInstance().ShowToast(CheckInV2TapIn.this,
                                                   "Could not get fare of Stage",
                                                   Toast.LENGTH_SHORT);
            xStageFare = 0;
        }
    }

    private TransactionValue CreateTransaction(String type, double topUpAmount, VoucherValue vv, boolean updateBalance)
    {
        TransactionValue trans = null;
        try
        {
            //---
            int adultCount = getSelectedPassengers(adult);
            int seniorCount = getSelectedPassengers(senior);
            int childCount = getSelectedPassengers(child);
            int disabledCount = getSelectedPassengers(disabled);
            //int exemptCount = getSelectedPassengers(exempt);
            int studentCount = getSelectedPassengers(student);

            String description = String.format("Check-in near %s",
                                               currentLocation.StationName);
			/*if (checkinType != Declarations.CHECK_IN_TYPE_TAP_IN)
				description += String.format(" for %d stages. ", stageCount);
			else
				description += "[@checkout]. ";*/
            description += "[@checkout]. ";

            if (adultCount > 0)
                description += String.format("Adult: %d,", adultCount);
            if (seniorCount > 0)
                description += String.format(" Senior: %d,", seniorCount);
            if (childCount > 0)
                description += String.format(" Child: %d,", childCount);
            if (disabledCount > 0)
                description += String.format(" Disabled: %d,", disabledCount);
            /*if (exemptCount > 0)
                description += String.format(" Exempt: %d,", exemptCount);*/
            if (studentCount > 0)
                description += String.format(" Student: %d,", studentCount);

            description = description.substring(0, description.length() - 1);

            trans = WorkingSession.getInstance().CreateTransaction(
                    CheckInV2TapIn.this,
                    "CHECK-IN",
                    type,
                    totalAmount,
                    0, //freight
                    0,//ExcessiveBag
                    topUpAmount,
                    vv,
                    currentLocation,
                    null,
                    xStageFare,
                    adultCount,
                    seniorCount,
                    childCount,
                    disabledCount,
                    0, //exemptCount,
                    studentCount,
                    null,
                    description
                                                                  );
            //--
            if (trans == null)
            {
                Message error = uiThreadHandler.CreateShowAlertDialogMsg(
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator. [1]"
                                                                        );
                uiThreadHandler.sendMessage(error);

                /*WorkingSession.getInstance().ShowErrorDialog(
                        CheckIn.this,
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator."
                );*/
                return null;
            }

			/*if (checkinType == Declarations.CHECK_IN_TYPE_NO_CARD ||
					checkinType == Declarations.CHECK_IN_TYPE_NORMAL) {
				trans.CheckOutDate = new Date();
			}*/

            try
            {
                long rx = db.addTransaction(trans);
                trans.ISN = (int) rx;
            }
            catch (Exception ex)
            {
                Message error = uiThreadHandler.CreateShowAlertDialogMsg(
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator. [2]"
                                                                        );
                uiThreadHandler.sendMessage(error);

                /*WorkingSession.getInstance().ShowErrorDialog(
                        CheckIn.this,
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator."
                );*/
                return null;
            }

            if (trans.ISN == 0)
            {
                Message error = uiThreadHandler.CreateShowAlertDialogMsg(
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator. [3]"
                                                                        );
                uiThreadHandler.sendMessage(error);

                /*WorkingSession.getInstance().ShowErrorDialog(
                        CheckIn.this,
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator."
                );*/
                return null;
            }

            WaitCardReaderOpenAndTapped();

            if (WorkingSession.getInstance().IsSmartCardTapped())
            {
                Log.d(TAG, "[CreateTransaction] Write check-in to card...");
                NfcCardInfo x = WorkingSession.getInstance().SAMCheckIn(
                        WorkingSession.getInstance().getLastTappedCardType(),
                                (float) currentLocation.Latitude, (float) currentLocation.Longitude,
                        0, 0);
                if (x != null)
                    Log.d(TAG, "[CreateTransaction] Write check-in to card successful");
                else
                    Log.d(TAG, "[CreateTransaction] Unable to write check-in to card");
            }

            //WorkingSession.getInstance().ShowToast(CheckIn.this, "Add transaction successful", Toast.LENGTH_SHORT);
            Message msg = uiThreadHandler.CreateShowToastMsg("Add transaction successful");
            uiThreadHandler.sendMessage(msg);
            //--
            if (updateBalance)
            {
                WorkingSession.getInstance().currentPassenger.CurrentBalance += trans.TopUpAmount - trans.FareAmount;
                int x = db.updateMemberBalance(
                        WorkingSession.getInstance().currentPassenger.ISN,
                        WorkingSession.getInstance().currentPassenger.CurrentBalance);
                if (x > 0)
                {
                    msg = uiThreadHandler.CreateShowToastMsg("Update customer balance successful");
                    uiThreadHandler.sendMessage(msg);
                    /*WorkingSession.getInstance().ShowToast(CheckIn.this,
                            "Update customer balance successful", Toast.LENGTH_SHORT);*/
                }
                else
                {
                    msg = uiThreadHandler.CreateShowToastMsg("Update customer balance failed");
                    uiThreadHandler.sendMessage(msg);
                    /*WorkingSession.getInstance().ShowToast(CheckIn.this,
                            "Update customer balance failed", Toast.LENGTH_SHORT);*/
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return trans;
    }

    private boolean WaitCardReaderOpenAndTapped()
    {
//        if(WorkingSession.getInstance().getSAM_NfcCardTapped() == -1)
//            WorkingSession.getInstance().OpenSAMCardReader(-1); //open with last information
        Log.d(TAG, "[WaitCardReaderOpenAndTapped] Waiting for card tapped in 10s");
        Date lastTest = new Date();
        long diffInSec = 0;
        try
        {
            do
            {
                Thread.sleep(200);
                long diffInMs = (new Date()).getTime() - lastTest.getTime();
                diffInSec = TimeUnit.MILLISECONDS.toSeconds(diffInMs);
                lastTest = new Date();
            }
            while (!WorkingSession.getInstance().IsSmartCardTapped() && diffInSec < 10); //waiting for 10s
        }
        catch (Exception ex)
        {
            Log.e(TAG, "[WaitCardReaderOpenAndTapped] Exception: " + ex);
            ex.printStackTrace();
            return false;
        }
        if (diffInSec >= 10)
            return false;
        return true;
    }

    private String CreateReceiptContent(TransactionValue xx)
    {
        Date date = new Date();
        String receiptDate = Utilities.DateToString(date, "dd/MM/yyyy");
        String receiptTime = Utilities.DateToString(date, "hh:mm a");

        String content = Utilities.StringAlignCenter(48, "BulaMy(Fiji) - BMF etikite  ") //+ "\n"
                + Utilities.StringAlignCenter(48, "BMF Make It Your Choice")
                + Utilities.StringAlignCenter(48, "www.bulamyfiji.com")
                + "\n\n"
                + Utilities.StringAlignLeftRight(48,
                                                 "Entry: " + currentLocation.StationName,
                                                 "Bus Reg.: " + WorkingSession.getInstance().journalBus.BusNumber
                                                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                                                 "Stages: " + stageCount,
                                                 "Driver: " + WorkingSession.getInstance().journalDriver.FullName
                                                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                                                 "No. PAX: " + String.valueOf(passengerCount),
                                                 "Company: DeeCees Fiji Ltd"
                                                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                                                 "Fare: " + WorkingSession.getInstance().decimalFormat.format(xStageFare),
                                                 "TIN: 12683467161"
                                                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                                                 "Total: " + String.valueOf(WorkingSession.getInstance().RoundMoney(totalAmount)),
                                                 "Issued: " + receiptDate
                                                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                                                 "ACCT Name: " + WorkingSession.getInstance().currentPassenger.getFullName(),
                                                 receiptTime
                                                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                                                 "ACCT #: " + WorkingSession.getInstance().currentPassenger.CardNumber,
                                                 "Mode: " + xx.Type
                                                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                                                 "Balance: " + WorkingSession.getInstance().decimalFormat.format(
                                                         WorkingSession.getInstance().currentPassenger.CurrentBalance),
                                                 "Transaction ID: " + xx.TransactionID
                                                ) + "\n"
                + "\nPlease Keep Receipt For Your Records\n\n";

        return content;
    }

    private boolean PrintReceipt(TransactionValue xx)
    {
		/*String x = db.getRuntimeValues("print-receipt");
		if(x == null || x.length() == 0)
			x = "1";
		if(x.equals("0"))
			return false;*/
        if (!WorkingSession.getInstance().printReceipt)
            return false;
        //--
        String receipt = CreateReceiptContent(xx);

        int rs = WorkingSession.getInstance().PreparePrintReceiptWifi(CheckInV2TapIn.this, receipt, printReceiptCallback);

        if (rs == Declarations.NO_WIFI_PRINTER_SETUP)
        {
            /*runOnUiThread(new Runnable()
            {
                @Override
                public void run()
                {
                    WorkingSession.getInstance().ShowToast(CheckIn.this, "No printer selected. Please setup one.", Toast.LENGTH_LONG);
                }
            });*/

            Message error = uiThreadHandler.CreateShowToastMsg(
                    "No printer selected. Please setup one.");
            uiThreadHandler.sendMessage(error);

            /*Message error = uiThreadHandler.CreateShowAlertDialogMsg(
                    "Print Receipt Error",
                    "No printer selected. Please setup one.");
            uiThreadHandler.sendMessage(error);*/

            //WorkingSession.getInstance().ShowToast(CheckIn.this, "No printer selected. Please setup one.", Toast.LENGTH_LONG);
        }
        else if (rs == Declarations.PRINT_RECEIPT_ERROR)
        {
            /*runOnUiThread(new Runnable()
            {
                @Override
                public void run()
                {
                    WorkingSession.getInstance().ShowToast(CheckIn.this, "Print receipt failed.", Toast.LENGTH_LONG);
                }
            });*/

            Message error = uiThreadHandler.CreateShowToastMsg(
                    "Print receipt failed.");
            uiThreadHandler.sendMessage(error);

            //WorkingSession.getInstance().ShowToast(CheckIn.this, "Print receipt failed.", Toast.LENGTH_LONG);
        }
        return rs == Declarations.PRINT_RECEIPT_WAITING;
    }

    private final Handler printReceiptCallback = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            Message error = null;
            switch (msg.what)
            {
                case Declarations.WIFI_PRINTER_CONNECTED:
                    WorkingSession.getInstance().ShowToast(CheckInV2TapIn.this,
                                                           "Printer connected", Toast.LENGTH_SHORT);
                    WorkingSession.getInstance().PrintReceipt();
                    break;
                case Declarations.WIFI_PRINTER_CONNECTED_ERR:
                    Log.d(TAG, String.format(
                                  "WIFI_PRINTER_CONNECTED_ERR. Unable connect to printer %s",
                                  WorkingSession.getInstance().wifiPrinterAddress)
                         );
                    /*WorkingSession.getInstance().ShowToast(CheckIn.this,
                            "Unable connect to printer", Toast.LENGTH_SHORT);*/
                    progress.dismiss();
                    //--
                    AlertDialog.Builder dialog = new AlertDialog.Builder(CheckInV2TapIn.this);
                    dialog.setNegativeButton("OK", new DialogInterface.OnClickListener()
                    {
                        @Override
                        public void onClick(DialogInterface dialog, int which)
                        {
                            uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
                        }
                    });
                    AlertDialog alert = dialog.create();
                    alert.setTitle("Print Receipt Error");
                    alert.setMessage(
                            String.format("Unable connect to printer %s",
                                          WorkingSession.getInstance().wifiPrinterAddress)
                                    );
                    //--
                    alert.show();
                    //--
                    break;
                case Declarations.WIFI_PRINTER_SEND_FAILED:
                    error = uiThreadHandler.CreateShowToastMsg(
                            "Unable send data to printer.");
                    uiThreadHandler.sendMessage(error);

                    /*WorkingSession.getInstance().ShowToast(CheckIn.this,
                            "Unable send data to printer", Toast.LENGTH_SHORT);*/
                    break;
                case Declarations.PRINT_RECEIPT_SUCCESSFUL:
                    error = uiThreadHandler.CreateShowToastMsg(
                            "Print receipt successful.");
                    uiThreadHandler.sendMessage(error);
                    /*WorkingSession.getInstance().ShowToast(CheckIn.this,
                            "Print receipt successful", Toast.LENGTH_SHORT);*/
                    //onBackPressed();
                    uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
                    break;
            }
        }
    };

    //this function is called in onActivityResult
    private void doPayCashAndTopUp(double inputAmount)
    {
        try
        {
            TransactionValue trans = CreateTransaction("Cash-TopUp", inputAmount, null, true);
            //-------------------TEST-------------------
            WorkingSession.getInstance().transactionCount++;
            //-------------------TEST-------------------
            uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
        }
        catch (Exception ex)
        {
            Log.e(TAG, "doPayCashAndTopUp: " + ex.getMessage());
            Message error = uiThreadHandler.CreateShowAlertDialogMsg(
                    "System Error",
                    ex.getMessage()
                                                                    );
            uiThreadHandler.sendMessage(error);
            /*WorkingSession.getInstance().ShowToast(CheckIn.this, ex.getMessage(),
                    Toast.LENGTH_LONG);*/
        }
    }

    //this function is called in onActivityResult
	/*private void doPayByStudentVoucher(
			String voucherType, double discountAmount,
			int collectBalanceType, double collectAmount)
	{
		try
		{
			VoucherValue vv = new VoucherValue();
			vv.VoucherType = voucherType;
			vv.VoucherAmount = discountAmount;

			TransactionValue trans = null;
			if (collectBalanceType == StudentVoucher.COMPLETE_PAYMENT_BY_VOUCHER)
			{
				trans = CreateTransaction(
						"Student-Voucher",
						0,
						vv,
						false);
			}
			else if (collectBalanceType == StudentVoucher.COMPLETE_PAYMENT_BY_BMF)
			{
				trans = CreateTransaction(
						"BMF",
						0,
						vv,
						false);
			}
			else if (collectBalanceType == StudentVoucher.COMPLETE_PAYMENT_BY_CASH)
			{
				trans = CreateTransaction(
						"Cash",
						collectAmount,
						vv,
						false);
			}
			if (trans == null)
			{
				WorkingSession.getInstance().ShowErrorDialog(
						CheckInV2TapIn.this,
						"Error",
						"System Error.\nCould not add Transaction"
				);
				return;
			}

			if (!PrintReceipt(trans))
			{
				uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
				//onBackPressed();
			}
		}
		catch (Exception ex)
		{
			Log.e(TAG, "doPayByStudentVoucher: " + ex.getMessage());
			Message error = uiThreadHandler.CreateShowAlertDialogMsg(
					"System Error",
					ex.getMessage()
			);
			uiThreadHandler.sendMessage(error);

            *//*WorkingSession.getInstance().ShowToast(CheckIn.this, ex.getMessage(),
                    Toast.LENGTH_LONG);*//*
		}
	}*/

    OnClickListener onCancelClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {

            onBackPressed();

        }
    };

    OnClickListener onSubmitClick = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            if (autoSubmit != null)
                autoSubmit.cancel();
            //--
            isAutoSubmit = false;
            //--
            String file2Play = "";
            File mp3File = new File(Environment.getExternalStorageDirectory() +
                                            Declarations.ShortHaul_sdCard_Folder + file2Play);
            if (InputValidate(0) == 0) //not validate or waiting for confirm
                return;
            else if (InputValidate(0) == 2) //Top up required
            {
                Intent runActivity = new Intent(CheckInV2TapIn.this, checkin_topup.class);
                runActivity.putExtra("REQUIRED_FARE_AMOUNT", minFare);
                startActivityForResult(runActivity, Declarations.REQUEST_REQUIRED_TOP_UP);
                return;
            }

            DoCheckInAsync xTask = new DoCheckInAsync(
                    CheckInV2TapIn.this,
                    progress,
                    DoCheckInAsync.CHECK_IN_BY_TAP_IN
            );

            if (WorkingSession.getInstance().IsSmartCardTapped())
            {
                file2Play = "process-complete.mp3";
            }
            else
            {
                file2Play = "process-error.mp3";
                WorkingSession.getInstance().ShowToast(
                        CheckInV2TapIn.this,
                        "Please tap card to the reader",
                        Toast.LENGTH_SHORT
                                                      );
            }
            // go back to Home

            if (!mp3File.exists())
            {
                errorVoice = null;
                WorkingSession.getInstance().ShowToast(
                        CheckInV2TapIn.this,
                        "File not found. " + mp3File.getAbsolutePath(),
                        Toast.LENGTH_SHORT
                                                      );
            }
            else
            {
                errorVoice = Utilities.PlayMedia(
                        CheckInV2TapIn.this,
                        file2Play);
            }
            xTask.execute();
        }


    };

    private void doTapIn()
    {
        try
        {
            TransactionValue trans = CreateTransaction("BMF", 0, null, false);
            if (trans == null)
                return;
            else
            {
                //  doRecordCheckIn();
            }
            //-------------------TEST-------------------
            WorkingSession.getInstance().transactionCount++;
            //-------------------TEST-------------------


            //autoSubmit.
            uiThreadHandler.sendEmptyMessage(UIThreadHandler.DO_BACK_PRESS);
            //onBackPressed();
        }
        catch (Exception ex)
        {
            WorkingSession.getInstance().ShowErrorDialog(
                    CheckInV2TapIn.this,
                    "System Error",
                    ex.getMessage());
        }
    }

    private boolean processing = false;

    @Override
    public void onBackPressed()
    {
        try
        {
            runOnUiThread(new Runnable()
            {
                @Override
                public void run()
                {
                    progress.dismiss();
                }
            });

        }
        catch (Exception ex)
        {
            Log.e(TAG, "[CheckInV2TapIn.onBackPress] " + ex.toString());
        }
        //--
        Intent next = new Intent(CheckInV2TapIn.this, Main.class);
        next.putExtra("INPUT_DIRECT_CHECK_IN", 0);
        if (Main.getInstance() != null)
            Main.getInstance().setIntent(next);
        //super.onBackPressed();
        //--
        finish();
    }

    private void backToMainWithInputMember(String cardNumber)
    {
        Intent mainScreen = new Intent(CheckInV2TapIn.this, Main.class);
        mainScreen.putExtra("INPUT_CUSTOMER", "++" + cardNumber);

        if (Main.getInstance() != null)
            Main.getInstance().setIntent(mainScreen);
        finish();
    }

    private String customerSwipeCard = "";

    @Override
    protected void onResume()
    {
        Log.d(TAG, "[onResume] ....");
        super.onResume();
        //--
        Log.d(TAG, "[onCreate] WorkingSession.getInstance().setSAMReaderEventListener(samReaderEvent, false);");
        WorkingSession.getInstance().setSAMReaderEventListener(samReaderEvent, false);
    }

    @Override
    protected void onPause()
    {
        Log.d(TAG, "[onPause] ....");
        super.onPause();

        if (errorVoice != null)
            errorVoice.stop();
        //WorkingSession.getInstance().CancelShowingToast();
        //--
        WorkingSession.getInstance().RestoreBackupSAMReaderEventListener();
    }

    @Override
    protected void onDestroy()
    {
        Log.d(TAG, "[onDestroy] ....");
        super.onDestroy();
        if (autoSubmit != null)
            autoSubmit.cancel();
        isAutoSubmit = false;
        if (errorVoice != null)
            errorVoice.stop();
        //--
        WorkingSession.getInstance().RestoreBackupSAMReaderEventListener();
    }

    private int lastCheckId = 0;
    private RadioGroup.OnCheckedChangeListener onPassengerCheckedChange = new RadioGroup.OnCheckedChangeListener()
    {
        @Override
        public void onCheckedChanged(RadioGroup radioGroup, int i)
        {
            Log.d(TAG, "[onPassengerCheckedChange] id: " + i);

            if (i == -1)
                return;
            //--
            if (i == lastCheckId)
                return;
            //--
            lastCheckId = i;
            //--
            if (!((RadioButton) findViewById(i)).isChecked())
                return;

            CalcTotalAmount();
            //--
            //String selectText = ((RadioButton) findViewById(radioGroup.getCheckedRadioButtonId())).getText().toString();

			/*if (selectText.equals("0"))
				return;
			if (checkinType == Declarations.CHECK_IN_TYPE_TAP_IN)
				return;*/
			/*//--
			if (radioGroup.getId() != R.id.Student)
			{
				Button button = (Button) findViewById(R.id.check_in2_payby_student_voucher);
				button.setEnabled(false);
				//--
				student.check(R.id.Student0);
			}
			else
			{
				Button button = (Button) findViewById(R.id.check_in2_payby_student_voucher);
				button.setEnabled(true);
				//--
				adult.check(R.id.Adult0);
				senior.check(R.id.Senior0);
				child.check(R.id.Child0);
				disabled.check(R.id.Disabled0);
				//exempt.check(R.id.Exempt0);
			}*/
        }
    };

    private final class UIThreadHandler extends Handler
    {
        private final String TAG = "CheckInUIThreadHandler";
        public static final int MSG_COUNT_DOWN = 0x10;
        public static final int SHOW_TOAST = 0x11;
        public static final int SHOW_ALERT_DIALOG = 0x12;
        public static final int DO_CHECK_IN_BY_CASH = 0x13;
        public static final int DO_BACK_PRESS = 0x14;
        private int currentCountDownValue = Declarations.TAP_IN_TIMEOUT_SECONDS;


        public UIThreadHandler(Looper lp)
        {
            super(lp);
        }

        @Override
        public void handleMessage(Message msg)
        {
            try
            {
                switch (msg.what)
                {
                    case UIThreadHandler.MSG_COUNT_DOWN:
                    {
                        Log.d(TAG, "Countdown: " + currentCountDownValue);
                        WorkingSession.getInstance().ShowToast(
                                CheckInV2TapIn.this,
                                String.valueOf(currentCountDownValue),
                                Toast.LENGTH_SHORT);
                        currentCountDownValue--;
                        if (currentCountDownValue < 0)
                        {
							/*autoSubmit.cancel();
							isAutoSubmit = false;*/
                            onSubmitClick.onClick(null);
                        }

                        break;
                    }
                    case UIThreadHandler.SHOW_TOAST:
                    {
                        String content = msg.getData().getString("TOAST_CONTENT", "");
                        if (content.length() == 0)
                            break;
                        WorkingSession.getInstance().ShowToast(
                                CheckInV2TapIn.this,
                                content,
                                Toast.LENGTH_SHORT);
                        break;
                    }
                    case UIThreadHandler.SHOW_ALERT_DIALOG:
                    {
                        String title = msg.getData().getString("DIALOG_TITLE", "");
                        String content = msg.getData().getString("DIALOG_CONTENT", "");
                        if (content.length() == 0)
                            break;
                        WorkingSession.getInstance().ShowErrorDialog(
                                CheckInV2TapIn.this,
                                title,
                                content);
                        break;
                    }
                    case DO_CHECK_IN_BY_CASH:
                    {
                        Thread.sleep(500);
                        Log.d(TAG, "Do Check-in by cash");
                        //--
                        DoCheckInAsync xTask = new DoCheckInAsync(
                                CheckInV2TapIn.this,
                                progress,
                                DoCheckInAsync.CHECK_IN_BY_CASH
                        );
                        xTask.execute();
                        //--
                        break;
                    }
                    case DO_BACK_PRESS:
                        Thread.sleep(500);
                        if (customerSwipeCard != null && customerSwipeCard.length() > 0)
                        {
                            runOnUiThread(new Runnable()
                            {
                                @Override
                                public void run()
                                {
                                    backToMainWithInputMember(customerSwipeCard);
                                }
                            });
                        }
                        else
                        {
                            runOnUiThread(new Runnable()
                            {
                                @Override
                                public void run()
                                {
                                    onBackPressed();
                                }
                            });
                        }
                }
            }
            catch (Exception ex)
            {
                Log.e(TAG, String.format("[MSG:%d] %s", msg.what, ex.getMessage()));
            }
        }

        public Message CreateShowToastMsg(String content)
        {
            Message msg = new Message();
            msg.what = SHOW_TOAST;

            Bundle data = new Bundle();
            data.putString("TOAST_CONTENT", content);
            msg.setData(data);

            return msg;
        }

        public Message CreateShowAlertDialogMsg(String dialogTitle, String content)
        {
            Message msg = new Message();
            msg.what = SHOW_ALERT_DIALOG;

            Bundle data = new Bundle();
            data.putString("DIALOG_TITLE", dialogTitle);
            data.putString("DIALOG_CONTENT", content);
            msg.setData(data);

            return msg;
        }
    }

    /*private boolean isMyFriendActive()
    {
        ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
        // get the info from the currently running task
        List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);

        Log.d(TAG, "CURRENT Activity :: "
                + taskInfo.get(0).topActivity.getClassName());
        String activeName = taskInfo.get(0).topActivity.getClassName();
        if (activeName.contains("valuecomusa.fijibus.eticket.shorthaul.CheckIn"))
            return true;
        return false;
    }*/

    private boolean touchOnStage = false;
    private View.OnTouchListener onTouch = new View.OnTouchListener()
    {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent)
        {
            Log.d(TAG, "onTouch: " + view.getId());
            if (view.isEnabled() && autoSubmit != null)
            {
                Log.d(TAG, "Cancel autoSubmit timer");
                autoSubmit.cancel();
                autoSubmit = null;
                isAutoSubmit = false;
            }

            if (isStageButton(view.getId()))
                touchOnStage = true;
            else
                touchOnStage = false;
            //--
            return false;
        }
    };

    private void RegisterPassengerTypeTouchEvent()
    {
        findViewById(R.id.Adult0).setOnTouchListener(onTouch);
        findViewById(R.id.Adult1).setOnTouchListener(onTouch);
        findViewById(R.id.Adult2).setOnTouchListener(onTouch);
        findViewById(R.id.Adult3).setOnTouchListener(onTouch);
        findViewById(R.id.Adult4).setOnTouchListener(onTouch);
        //findViewById(R.id.Adult5).setOnTouchListener(onTouch);
        //--
        findViewById(R.id.Senior0).setOnTouchListener(onTouch);
        findViewById(R.id.Senior1).setOnTouchListener(onTouch);
        findViewById(R.id.Senior2).setOnTouchListener(onTouch);
        findViewById(R.id.Senior3).setOnTouchListener(onTouch);
        findViewById(R.id.Senior4).setOnTouchListener(onTouch);
        //findViewById(R.id.Senior5).setOnTouchListener(onTouch);
        //--
        findViewById(R.id.Child0).setOnTouchListener(onTouch);
        findViewById(R.id.Child1).setOnTouchListener(onTouch);
        findViewById(R.id.Child2).setOnTouchListener(onTouch);
        findViewById(R.id.Child3).setOnTouchListener(onTouch);
        findViewById(R.id.Child4).setOnTouchListener(onTouch);
        //findViewById(R.id.Child5).setOnTouchListener(onTouch);
        //--
        findViewById(R.id.Disabled0).setOnTouchListener(onTouch);
        findViewById(R.id.Disabled1).setOnTouchListener(onTouch);
        findViewById(R.id.Disabled2).setOnTouchListener(onTouch);
        findViewById(R.id.Disabled3).setOnTouchListener(onTouch);
        findViewById(R.id.Disabled4).setOnTouchListener(onTouch);
        //findViewById(R.id.Disabled5).setOnTouchListener(onTouch);
        //--
        /*findViewById(R.id.Exempt0).setOnTouchListener(onTouch);
        findViewById(R.id.Exempt1).setOnTouchListener(onTouch);
        findViewById(R.id.Exempt2).setOnTouchListener(onTouch);
        findViewById(R.id.Exempt3).setOnTouchListener(onTouch);
        findViewById(R.id.Exempt4).setOnTouchListener(onTouch);
        findViewById(R.id.Exempt5).setOnTouchListener(onTouch);*/
        //--
        findViewById(R.id.Student0).setOnTouchListener(onTouch);
        findViewById(R.id.Student1).setOnTouchListener(onTouch);
        /*findViewById(R.id.Student2).setOnTouchListener(onTouch);
        findViewById(R.id.Student3).setOnTouchListener(onTouch);
        findViewById(R.id.Student4).setOnTouchListener(onTouch);
        findViewById(R.id.Student5).setOnTouchListener(onTouch);*/
    }

    private void RegisterStageTouchEvent()
    {
        findViewById(R.id.checkin_btStage1).setOnTouchListener(onTouch);
        findViewById(R.id.checkin_btStage2).setOnTouchListener(onTouch);
        findViewById(R.id.checkin_btStage3).setOnTouchListener(onTouch);
        findViewById(R.id.checkin_btStage4).setOnTouchListener(onTouch);
        findViewById(R.id.checkin_btStage5).setOnTouchListener(onTouch);
        findViewById(R.id.checkin_btStage6).setOnTouchListener(onTouch);
        findViewById(R.id.checkin_btStage7).setOnTouchListener(onTouch);
        findViewById(R.id.checkin_btn_tap_out).setOnTouchListener(onTouch);
    }

    private boolean isStageButton(int checkId)
    {
        return checkId == R.id.checkin_btStage1
                || checkId == R.id.checkin_btStage2
                || checkId == R.id.checkin_btStage3
                || checkId == R.id.checkin_btStage4
                || checkId == R.id.checkin_btStage5
                || checkId == R.id.checkin_btStage6
                || checkId == R.id.checkin_btStage7;
    }

    public class DoCheckInAsync extends AsyncTask<Object, Void, Void>
    {
        public static final int CHECK_IN_BY_BMF = 1000;
        public static final int CHECK_IN_BY_CASH = 1001;
        public static final int CHECK_IN_BY_CASH_TOP_UP = 1002;
        public static final int CHECK_IN_BY_STUDENT_VOUCHER = 1003;
        public static final int CHECK_IN_BY_TAP_IN = 1004;

        private ProgressDialog progress;
        private Context callerContext;
        private int checkInType;

        public DoCheckInAsync(Context context, ProgressDialog dialog, int checkInType)
        {
            callerContext = context;
            progress = dialog;
            this.checkInType = checkInType;
        }

        public void onPreExecute()
        {
            processing = true;
            progress.show();
            //--
            super.onPreExecute();
        }

        public Void doInBackground(Object... inputValues)
        {
            try
            {
                switch (this.checkInType)
                {
					/*case CHECK_IN_BY_CASH:
						doPayByCash();
						break;
					case CHECK_IN_BY_BMF:
						doPayByBMF();
						break;*/
                    case CHECK_IN_BY_TAP_IN:
                        doTapIn();
                        break;
                    case CHECK_IN_BY_CASH_TOP_UP:
                        doPayCashAndTopUp(((Number) inputValues[0]).doubleValue());
                        break;
					/*case CHECK_IN_BY_STUDENT_VOUCHER:
						doPayByStudentVoucher(
								String.valueOf(inputValues[0]), //voucherType
								((Number) inputValues[1]).doubleValue(), //discountAmount
								((Number) inputValues[2]).intValue(), //collectBalanceType
								((Number) inputValues[3]).doubleValue() //collectAmount
						);*/
                }
            }
            catch (Exception ex)
            {
                Log.e(TAG, "[DoCheckInAsync] " + ex.getMessage());
            }

            return null;
        }

        public void onPostExecute(Void unused)
        {
            processing = false;
            super.onPostExecute(unused);
        }
    }

    //added by lhdung Dec.2014
    private Enums.CardProvider tappedCardType;
    private WorkingSession.SAMReaderEvent samReaderEvent = new WorkingSession.SAMReaderEvent()
    {
        @Override
        public void OnReaderStateChange(String state)
        {
            Log.d(TAG, "[SAMReaderEvent.OnReaderStateChange] " + state);
            WorkingSession.getInstance().ShowToast(
                    CheckInV2TapIn.this,
                    "Card Reader " + state,
                    Toast.LENGTH_SHORT
            );
        }

        @Override
        public void OnSAMSlotStateChange(int slot, String state)
        {
            Log.d(TAG, String.format("[SAMReaderEvent.OnSAMSlotStateChange] Slot  %d state %s", slot, state));

        }

        @Override
        public void OnSmartCardInteraction(Enums.CardProvider cardProvider, int status, String description)
        {

            if (status == Declarations.SMART_CARD_STATE_PRESENT) //tap in
            {
                Log.d(TAG, String.format("[SAMReaderEvent.OnSmartCardInteraction] %s tapped. Card status  %d, %s",
                        cardProvider.toString(), status, description));
                //do process tap in
                tappedCardType = cardProvider;
            }
            else //may be tap out
            {
                Log.d(TAG, String.format("[SAMReaderEvent.OnSmartCardInteraction] %s removed. Card status  %d, %s",
                        cardProvider.toString(), status, description));
            }
        }
    };

}
